# 👉 Web 性能优化

# 首屏优化

# 加载阶段的优化

加载阶段是指从发出请求到渲染出完整页面的过程,影响到这个阶段的主要因素有网络和 JavaScript 脚本。

  1. 减少关键资源的个数

1)通过内联关键 JavaScript、内联关键 CSS,移除这两种类型的文件下载,这样获取到 HTML 文件之后就可以直接开始渲染流程了。

如果资源是“渲染阻止”,则意味着浏览器在下载或处理该资源之前无法显示该页面。

2)另一种方式,如果 JavaScript 代码没有 DOM 或者 CSSOM 的操作,则可以改成 async 或者 defer 属性。大的 CSS 文件,可以通过媒体查询属性,将其拆分为多个不同用途的 CSS 文件,这样只有在特定的场景下才会加载特定的 CSS 文件。

  1. 压缩关键资源大小

可以压缩 CSS 和 JavaScript 资源,移除 HTML、CSS、JavaScript 文件中一些注释内容,gzip

  1. 减少域名查询

DNS 查询和解析域名也是消耗时间的,所以要减少对外部 JS、CSS、图片等资源的引用,不同域名的使用越少越好。

  1. 减少关键资源 RTT 的次数

RTT 就是这里的往返时延。它是网络中一个重要的性能指标,表示从发送端发送数据开始,到发送端收到来自接收端的确认,总共经历的时延。通常 1 个 HTTP 的数据包在 14KB 左右,所以 1 个 0.1M 的页面就需要拆分成 8 个包来传输了,也就是说需要 8 个 RTT。

可通过减少关键资源的个数和减少关键资源的大小搭配来实现。除此之外,还可以使用 CDN 来减少每次 RTT 时长。

# 预加载

  1. dns-prefetch
<!-- DNS解析的速度可用通过下面的标签来进行预解析 -->
<link rel=”dns-prefetch” href=”//weibo.com”>

# 按需加载

# 懒加载

# 使用缓存

# 网络相关

# 浏览器 http 同域名并发请求限制(http1.1 - 域名分片)

# 采取 HTTP2

# dns 解析(如何优化)

# tcp http

# cdn

# 缓存策略

浏览器通常限制对同一个域名最多只允许创建 6 个长连接,因此可以通过将域名分散至多个域名。(PS:域名解析时间会变多)

# 构建相关

构建方面通过合理的配置构建工具,达到减少生产环境的代码的体积,减少打包时间,缩短页面加载时间

# webpack 优化配置

环境:@vue/cli:4.0.5 、webpack:4.31.0

vue-cli 提供了两种方式来更改 webpack 配置:

  1. 原生配置方式,配置的结果将会被 webpack-merge 合并入最终的 webpack 配置。
// vue.config.js
module.exports = {
    configureWebpack: (config) => {
        // 直接书写webpack配置项...
        if (isProduction) {
            // ...
        } else {
            // ...
        }

        //直接修改配置
        // config.resolve.alias["@asset"] = resolve("src/assets");
    },
};
  1. 链式配置方式,vue-cli 内部是使用 webpack-chain 这个插件来维护 webpack 配置的,因为能更细粒度的控制其内部配置,因此也是官方比较推荐的一个方式。
// vue.config.js
module.exports = {
    chainWepack: (config) => {
        config.resolve.alias
            .set("@", resolve("src"))
            .set("@assets", resolve("src/assets"))
            .set("@components", resolve("src/components"));
    },
};

可通过vue inspect > output.js查看 vue-cli3 项目默认的 webpack 配置详情。

# 优化打包体积

  1. 使用 webpack-bundle-analyzer 分析打包体积;

它将 bundle 内容展示为便捷的、交互式、可缩放的树状图形式。

// npm install webpack-bundle-analyzer --dev

// vue.config.js
const BundleAnalyzerPlugin = require("webpack-bundle-analyzer")
    .BundleAnalyzerPlugin;

module.exports = {
    configureWebpack: {
        plugins: [new BundleAnalyzerPlugin()],
    },
};
  1. 使用splitChunks抽取公共代码

webpack4 之前使用 commonChunkPlugin,webpack4 之后使用 splitChunks。

# 优化打包速度

  1. 使用speed-measure-webpack-plugin
// vue.config.js
const SpeedMeasurePlugin = require("speed-measure-webpack-plugin");
const smp = new SpeedMeasurePlugin();

module.exports = {
  // 这里无法使用链式写法chainWebpack,会报错
  configureWebpack: smp.wrap({
    // ... webpack config goes here ...
  }
}

# 路由懒加载

# 静态资源优化

# 图片懒加载

# 浏览器渲染过程

# 避免回流和重绘

# 防抖和节流处理

# 第三方插件的按需引入

# 适当采用 keep-alive 缓存组件

# createDocumentFragment 创建文档碎片节点

通过 document.createDocumentFragment() 创建文档碎片节点,对 DOM 进行批量操作,减少频繁修改 DOM。